package com.lds.erp.gateway.interceptor;

import java.io.IOException;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dph.common.utils.interceptor.AbstractInterceptorHandler;
import com.dph.common.utils.interceptor.WebInterceptorUrlConfiguration;
import com.dph.common.utils.utils.AppUtils;
import com.dph.common.utils.utils.SignUtils;
import com.google.common.collect.Maps;
import com.lds.erp.base.RequestWrapper;
import com.lds.erp.common.AppEnum;
import com.lds.erp.configuration.ConfigProperty;
import com.lds.erp.util.JsonUtils;
import com.lds.erp.util.SpringContextUtils;
import com.lds.erp.util.SpringRequestUtils;

/**
 * @author hongsir
 * @apiNote 摘要:移动端验签拦截器
 * @date 2019-01-10 13:46
 */
@WebInterceptorUrlConfiguration(priority = 1, include = "/api/app/**",exclude = {"/api/app/merchant/product/product_detail",
        "/api/app/merchant/mchinfo/insertMchInfoFrequentPurchase","/api/app/merchant/product/product_spec_detail",
        "/api/app/message/messageDetails"})
public class SignValidInterceptor extends AbstractInterceptorHandler {
    private static final Logger log = LoggerFactory.getLogger(SignValidInterceptor.class);
    public static final String SING_PARAM_KEY = "isign";
    public static final String TOKEN_PARAM_KEY = "token";
    public static final String FAIL_MESSAGE = "签名验证失败";

    public SignValidInterceptor() {
        // 开发模式取消验签
        log.info("<<<载入移动端验签拦截器(SignValidInterceptor:/api/app/**)>>>");
    }

    public static boolean validGetSign(HttpServletRequest request) {
        //小程序不走验签
        if (checkMCHMP(request)) {
            return true;
        }
    	ConfigProperty config = SpringContextUtils.getBean(ConfigProperty.class);
        Map<String, String> paramMap = AppUtils.getRequestMap(request);
        String token = request.getHeader(TOKEN_PARAM_KEY);
        if (StringUtils.isBlank(token)) {
            token = paramMap.get(TOKEN_PARAM_KEY);
        }
        if (StringUtils.isNotBlank(token)) {
            paramMap.put(TOKEN_PARAM_KEY, token);
        }
        paramMap.put(SING_PARAM_KEY, request.getHeader(SING_PARAM_KEY));
        log.info("GET签名参数:{}", paramMap);

        return SignUtils.checkSign(paramMap, config.getSignKey());
    }


    public static boolean test(HttpServletRequest request) throws IOException {
    	ConfigProperty config = SpringContextUtils.getBean(ConfigProperty.class);
        String token = request.getHeader(TOKEN_PARAM_KEY);
        Map<String, String> paramMap = Maps.newHashMap();
        if (StringUtils.isNotBlank(token)) {
            paramMap.put(TOKEN_PARAM_KEY, token);
        }
        //new RequestWrapper(request);
        String signBody = RequestWrapper.TEMP.get();
        JSONObject json = JSON.parseObject(signBody);
        String dataStr = json.getString("data");

        paramMap.put("data", dataStr);
        paramMap.put("isign", request.getHeader("isign"));
        return SignUtils.checkSign(paramMap, config.getSignKey());
    }


    public static boolean validPostSign(HttpServletRequest request) throws IOException {
        //小程序不走验签
        if (checkMCHMP(request)){
            return true;
        }

    	ConfigProperty config = SpringContextUtils.getBean(ConfigProperty.class);
        String token = request.getHeader(TOKEN_PARAM_KEY);
        Map<String, String> paramMap = Maps.newHashMap();
        if (StringUtils.isNotBlank(token)) {
            paramMap.put(TOKEN_PARAM_KEY, token);
        }
        //new RequestWrapper(request);
        String signBody = RequestWrapper.TEMP.get();
        JSONObject json = JSON.parseObject(signBody);
        String dataStr = json.getString("data");

        paramMap.put("data", dataStr);
        paramMap.put("isign", request.getHeader("isign"));
        return SignUtils.checkSign(paramMap, config.getSignKey());
    }


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //小程序不走验签
        if (checkMCHMP(request)) {
            return true;
        }

        // 开发模式取消验签
        ConfigProperty config = SpringContextUtils.getBean(ConfigProperty.class);
        if (config.getDeveloperMode()) {
            return true;
        }
        log.info("3.进入签名验证:{}", request.getRequestURI());
        String method = request.getMethod();
        boolean ok;
        // POST请求入参验签
        if (HttpMethod.POST.matches(method)) {
            ok = validPostSign(request);
        }
        // GET请求入参验签
        else if (HttpMethod.GET.matches(method)) {
            ok = validGetSign(request);
        }
        // 其他方式请求暂不允许
        else {
            SpringRequestUtils.responseJson(response, JsonUtils.fail("暂不接受非(GET/POST)请求方式"));
            return false;
        }

        if (!ok) {
            SpringRequestUtils.responseJson(response, JsonUtils.fail(FAIL_MESSAGE));
            return false;
        }
        return true;
    }

    /**
     *
     * @param request
     * @return
     */
    private static boolean checkMCHMP(HttpServletRequest request) {
        String appStr = request.getHeader("app");
        AppEnum app = AppEnum.getEnumByCode(appStr);
        if (AppEnum.MCHMP.equals(app)) {
            return true;
        }
        return false;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        RequestWrapper.TEMP.remove();
    }
}
